package com.deer.wms.ASN.manage.web;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deer.wms.ASN.manage.constant.AsnManageConstant;
import com.deer.wms.ASN.manage.model.AcceptEx;
import com.deer.wms.ASN.manage.model.AcceptExCriteria;
import com.deer.wms.ASN.manage.model.AcceptExDto;
import com.deer.wms.ASN.manage.model.InputAsnMaster;
import com.deer.wms.ASN.manage.model.asn.*;
import com.deer.wms.ASN.manage.model.asn.CreateASN.*;
import com.deer.wms.ASN.manage.model.file.AsnMasterFileCriteria;
import com.deer.wms.ASN.manage.model.file.FileData;
import com.deer.wms.ASN.manage.model.in.AcceptRecord;
import com.deer.wms.ASN.manage.model.in.AcceptRecordCriteria;
import com.deer.wms.ASN.manage.service.*;
import com.deer.wms.base.system.model.Area.AreaInfo;
import com.deer.wms.base.system.model.Item.ItemInfo;
import com.deer.wms.base.system.model.Pack.PackDetail;
import com.deer.wms.base.system.model.Supplier.SupplierManage;
import com.deer.wms.base.system.service.CellInfoService;
import com.deer.wms.base.system.service.ItemInfoService;
import com.deer.wms.base.system.service.PackDetailService;
import com.deer.wms.base.system.service.SupplierManageService;
import com.deer.wms.intercept.annotation.User;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.inventory.model.Inventory.Inventory;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.inventory.service.InventoryTransactService;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.core.result.Result;
import com.deer.wms.project.root.core.result.ResultGenerator;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.util.DateUtils;
import com.deer.wms.project.root.util.Excel;
import com.deer.wms.project.root.util.ExcelUtils;
import com.deer.wms.review.manage.model.BillRecord;
import com.deer.wms.review.manage.service.BillRecordService;
import com.deer.wms.review.manage.service.CaseMasterService;
import com.deer.wms.system.manage.model.carrier.Carrier;
import com.deer.wms.system.manage.model.organization.Organization;
import com.deer.wms.system.manage.model.user.UserInfo;
import com.deer.wms.system.manage.model.ware.WareInfo;
import com.deer.wms.system.manage.service.*;
import com.deer.wms.ware.task.model.SO.SoMaster;
import com.deer.wms.ware.task.service.PushErpService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.deer.wms.project.root.util.CollectionUtils.convertMap;

/**
 * Created by guo on 2020/01/03.
 */
@Api(description = "ASN信息api接口")
@RestController
@RequestMapping("/asn/masters")
@Transactional
public class AsnMasterController {

    @Autowired
    private AsnMasterService asnMasterService;

    @Autowired
    private AsnDetailService asnDetailService;

    @Autowired
    private CaseMasterService caseMasterService;

    @Autowired
    private ValidatorService validatorService;

    @Autowired
    private WareInfoService wareInfoService;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private SupplierManageService supplierManageService;

    @Autowired
    private CarrierService carrierService;

    @Autowired
    private ItemInfoService itemInfoService;

    @Autowired
    private PackDetailService packDetailService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private BillRecordService billRecordService;

    @Autowired
    private AcceptExService acceptExService;

    @Autowired
    private AcceptRecordService acceptRecordService;

    @Autowired
    private InventoryTransactService inventoryTransactService;

    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private AsnShipDetailService asnShipDetailService;

    @ApiOperation(value = "ERP--》WMS生成入库单", notes = "ERP--》WMS生成入库单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/createASN")
    public Result createASN(@RequestBody CreateASN createASN, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        String wareCode = createASN.getWareCode();
        String orgCode = createASN.getOrgCode();
        AsnMaster asnMaster = asnMasterService.findBy("bill_no", createASN.getBillNo());
        if (asnMaster != null) {
            return ResultGenerator.genFailResult(CommonCode.BILL_NO, null);
        }
        if (wareCode == null) {
            return ResultGenerator.genFailResult(CommonCode.WARE_NULL, null);
        }
        if (orgCode == null) {
            return ResultGenerator.genFailResult(CommonCode.ORG_NULL, null);
        }

//        if(createASN.getShipList()!=null){
//            for (CreateASNShipDetail createASNShipDetail:createASN.getShipList()
//            ) {
//                AsnShipDetail asnShipDetail = asnShipDetailService.findBy("ship_bill_code",createASNShipDetail.getShipBillCode());
//                if(asnShipDetail!=null){
//                    return ResultGenerator.genFailResult(CommonCode.SHIP_CODE);
//                }
//            }
//        }
        List<CreateASNSKUDetail> asnskuDetails = createASN.getSkuList();
        for (int i = 0; i < asnskuDetails.size(); i++) {
            CreateASNSKUDetail createASNSKUDetail = asnskuDetails.get(i);
            ItemInfo itemInfo = itemInfoService.findBy("item_code", createASNSKUDetail.getSkuCode());
            if (itemInfo != null && createASNSKUDetail.getSkuName() != null && !createASNSKUDetail.getSkuName().equals("")) {
                itemInfo.setItemName(createASNSKUDetail.getSkuName());

            }
            if (itemInfo != null && createASNSKUDetail.getImgUrl() != null && !createASNSKUDetail.getImgUrl().equals("")) {

                itemInfo.setImgUrl(createASNSKUDetail.getImgUrl());
            }
        }
        asnMasterService.createASN(createASN, currentUser);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "ERP--》WMS推送入库快递单号", notes = "WMS推送入库快递单号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/addInShipNo")
    public Result addInShipNo(@RequestBody AddInShipNo addInShipNo, @ApiIgnore @User CurrentUser currentUser) {

        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        AsnShipDetail asnShipDetail = asnShipDetailService.findBy("ship_bill_code", addInShipNo.getShipBillNo());
        if (asnShipDetail == null) {
            asnShipDetail = new AsnShipDetail();
            asnShipDetail.setBillNo(addInShipNo.getBillNo());
            asnShipDetail.setShipBillCode(addInShipNo.getShipBillNo());
            asnShipDetail.setShipCode(addInShipNo.getShipCode());
            asnShipDetailService.save(asnShipDetail);
        }
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "ERP--》WMS修改数量", notes = "WMS修改数量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/updateSkuQuantity")
    public Result updateSkuQuantity(@RequestBody UpdateSkuQuantity updateSkuQuantity, @ApiIgnore @User CurrentUser currentUser) {

        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        AsnMaster asnMaster = asnMasterService.findSoByBillNo(updateSkuQuantity.getBillNo(), updateSkuQuantity.getWareCode());
        if (asnMaster == null) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "单号无效！");
        }
        if (!asnMaster.getWareCode().equals(updateSkuQuantity.getWareCode())) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "仓库编码异常：" + asnMaster.getWareCode() + "||" + updateSkuQuantity.getWareCode());
        }
        if (updateSkuQuantity.getBillNo() == null || updateSkuQuantity.getBillNo().equals("")) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "没有传单号！");
        }
        List<Sku> skuList = updateSkuQuantity.getSkuList();
        for (Sku sku : skuList) {
            if (sku.getQuantity() == null || sku.getQuantity() < 0) {
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "数量必须大于0！");
            }
        }

        AcceptExCriteria acceptExCriteria = new AcceptExCriteria();
        acceptExCriteria.setBillNo(updateSkuQuantity.getBillNo());
        List<AcceptExDto> acceptExs = acceptExService.findList(acceptExCriteria);
        if (acceptExs.size() > 0) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "该入库单已经有验收异常记录！");
        }
        AcceptRecordCriteria acceptRecordCriteria = new AcceptRecordCriteria();
        acceptRecordCriteria.setAsnBillNo(updateSkuQuantity.getBillNo());
        List<AcceptRecord> acceptRecords = acceptRecordService.findList(acceptRecordCriteria);
        if (acceptRecords.size() > 0) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "该订单已进行入库！");
        }
        if (!asnMaster.getWareCode().equals(updateSkuQuantity.getWareCode())) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "仓库编码异常：" + asnMaster.getWareCode() + "||" + updateSkuQuantity.getWareCode());
        }
        for (Sku sku : skuList) {
            List<AsnDetail> list = asnDetailService.findByBillNo(updateSkuQuantity.getBillNo());
            for (AsnDetail asnDetail : list) {
                if (asnDetail.getItemCode().equals(sku.getSkuCode())) {
                    asnDetail.setExpectQuantity(sku.getQuantity());
                    asnDetailService.updateById(asnDetail);
                }
            }
        }
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "ERP--》WMS推送入库异常解决方案", notes = "ERP--》WMS推送入库异常解决方案")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/addInExResult")
    public Result addInExResult(@RequestBody InExResult inExResult, @ApiIgnore @User CurrentUser currentUser) {

        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }

        AcceptEx acceptEx = acceptExService.getById(Integer.parseInt(inExResult.getQcNo()));
        acceptEx.setFangan(inExResult.getExFangan());
        InExResult.ReturnInfo returnInfo = new InExResult.ReturnInfo();
        acceptEx.setReturnArea(returnInfo.getArea());
        acceptEx.setReturnCity(returnInfo.getCity());
        acceptEx.setReturnCountry(returnInfo.getCountry());
        acceptEx.setReturnDetailAddress(returnInfo.getDetailAddress());
        acceptEx.setReturnProvince(returnInfo.getProvince());
        acceptEx.setReturnLinkMan(returnInfo.getLinkMan());
        acceptEx.setReturnLinkPhone(returnInfo.getLinkPhone());
        acceptEx.setReturnExpressBillUrl(returnInfo.getExpressBillUrl());
        acceptEx.setReturnShipCode(returnInfo.getShipCode());
        acceptEx.setReturnShipBillCode(returnInfo.getShipBillCode());
        acceptEx.setState(2);
        acceptExService.updateById(acceptEx);
        return ResultGenerator.genSuccessResult();


    }


    @ApiOperation(value = "新增ASN信息", notes = "新增ASN信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/insert")
    public Result add(@RequestBody AsnData asnData, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        String tableName = "asn_master";
        Integer nextId = validatorService.getNextId(tableName);

        String billNo = "ASN" + "-" + nextId;
        asnData.getAsnMaster().setBillNo(billNo);
        asnMasterService.createAsnMaster(asnData, currentUser);
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "审核", notes = "审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @GetMapping("/review")
    public Result review(String billNo, Integer reviewResult, Integer caseDetailId, String memo, @ApiIgnore @User CurrentUser currentUser) {
        AsnMaster asnMaster = asnMasterService.findBy("bill_no", billNo);
        //-1不通过   0-流转中  1-通过  2-初始化
        Integer lastReviewResult = caseMasterService.review(caseDetailId, currentUser.getUserId(), reviewResult, memo);


        if (lastReviewResult == -1) {
            asnMaster.setState(-1);
            asnMasterService.updateById(asnMaster);
            BillRecord billRecord = billRecordService.findByBillNoAndType(billNo, 3);//ASN审核
            billRecord.setResult("退回");
            billRecord.setModifyTime(DateUtils.getNowDateTimeString());
            billRecord.setModifyUserId(currentUser.getUserId());
            billRecord.setModifyUserName(currentUser.getUserName());
            billRecordService.updateById(billRecord);
        } else if (lastReviewResult == 0) {
            asnMaster.setState(0);
            asnMasterService.updateById(asnMaster);
            BillRecord billRecord = billRecordService.findByBillNoAndType(billNo, 3);//ASN审核
            billRecord.setResult("流转");
            billRecordService.updateById(billRecord);
        } else if (lastReviewResult == 2) {
            asnMaster.setState(2);
            asnMasterService.updateById(asnMaster);
        } else if (lastReviewResult == 1) {
            asnMaster.setState(1);
            asnMasterService.updateById(asnMaster);
            BillRecord billRecord = billRecordService.findByBillNoAndType(billNo, 3);//ASN审核
            billRecord.setResult("通过");
            billRecord.setModifyTime(DateUtils.getNowDateTimeString());
            billRecord.setModifyUserId(currentUser.getUserId());
            billRecord.setModifyUserName(currentUser.getUserName());
            billRecordService.updateById(billRecord);
        }
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "重新发起审核", notes = "重新发起审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @GetMapping("/reReview")
    public Result reReview(String billNo, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        AsnMaster asnMaster = asnMasterService.findBy("bill_no", billNo);

        //初始化状态 2
        asnMaster.setState(2);
        asnMasterService.updateById(asnMaster);
        caseMasterService.createCase(billNo, 2, currentUser.getUserId(), asnMaster.getWareId(), asnMaster.getOrganizationId());

        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "增删master、detail", notes = "增删master、detail")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/update")
    public Result update(@RequestBody AsnData asnData, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        AsnMaster asnMaster = asnData.getAsnMaster();
        asnMasterService.updateById(asnMaster);

        List<AsnDetail> asnDetails = asnData.getAsnDetails();

        for (int i = 0; i < asnDetails.size(); i++) {
            AsnDetail asnDetail = asnDetails.get(i);
            String detailNo = asnData.getAsnMaster().getBillNo() + "-" + (i + 1);
            asnDetail.setDetailNo(detailNo);
            asnDetail.setBillNo(asnData.getAsnMaster().getBillNo());
            asnDetail.setDetailNo(detailNo);

            if (asnData.getInsertType() == -2) {
                asnDetail.setState(2);
            } else if (asnData.getInsertType() == 0) {
                asnDetail.setState(0);
            }
            asnDetailService.updateById(asnDetail);
        }
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/detail")
    public Result detail(@PathVariable Integer id) {
        AsnMaster asnMaster = asnMasterService.getById(id);
        return ResultGenerator.genSuccessResult(asnMaster);
    }


    @GetMapping("/delete")
    public Result delete(Integer id) {
        AsnMaster asnMaster = asnMasterService.getById(id);
        asnDetailService.remove(new QueryWrapper<AsnDetail>().eq("bill_no", asnMaster.getBillNo()));
        acceptRecordService.remove(new QueryWrapper<AcceptRecord>().eq("asn_bill_no", asnMaster.getBillNo()));
        inventoryService.remove(new QueryWrapper<Inventory>().eq("asn_bill_no", asnMaster.getBillNo()));
        asnMasterService.removeById(id);

        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("close")
    public Result close(Integer id) {
        AsnMaster asnMaster = asnMasterService.getById(id);
        asnMaster.setAsnState(AsnManageConstant.ASN_CLOSE);
        asnMasterService.updateById(asnMaster);


        return ResultGenerator.genSuccessResult();

    }


    @GetMapping("/list")
    public Result list(AsnMasterCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<AsnMasterDto> list = asnMasterService.findList(criteria);
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @GetMapping("/pdaList")
    public Result pdaList(AsnMasterCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), 10);
        List<AsnMasterDto> list = asnMasterService.findPdaList(criteria);
        // 过滤掉产品入库
        list = list.stream().filter(asnMasterDto -> asnMasterDto.getAsnType() != 2).collect(Collectors.toList());
        // 过滤掉先发配件出库
        list = list.stream().filter(asnMasterDto -> ObjectUtil.notEqual(asnMasterDto.getMemo(), "先发配件")).collect(Collectors.toList());

        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @GetMapping("/qcList")
    public Result qcList(AsnMasterCriteria criteria) {
        String billNo = criteria.getKeyWords();
        AsnMaster asnMaster = asnMasterService.getOne(new QueryWrapper<AsnMaster>()
                .eq("bill_no", billNo)
        );

        if (ObjectUtil.isNotEmpty(asnMaster)&&asnMaster.getAsnState().equals(AsnManageConstant.ASN_CLOSE)) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "任务单已关闭");
        }


        if (ObjectUtil.isEmpty(criteria.getKeyWords())) {
            return ResultGenerator.genSuccessResult();
        }
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<AsnMasterDto> list = asnMasterService.findQcList(criteria);
        List<AsnMasterDto> limtList = list.stream().limit(1).collect(Collectors.toList());
        if (ObjectUtil.isEmpty(limtList)) {
            List<AcceptRecord> acceptRecords = acceptRecordService.list(new QueryWrapper<AcceptRecord>().in("asn_bill_no", criteria.getKeyWords().trim()));
            if (ObjectUtil.isEmpty(acceptRecords)) {
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "任务单未收货");

            }

            long count = acceptRecords.stream().filter(item -> item.getPackedQuantity() > 0).count();
            if (count > 0) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "该任务单已装箱");
            }
        }


        PageInfo pageInfo = new PageInfo(limtList);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @GetMapping("/findByBillNo")
    public Result findByBillNo(String billNo) {
        //列表详情
        AsnMaster asnMaster = asnMasterService.getOneByField("bill_no", billNo.trim());


        List<AsnDetail> asnDetails = asnDetailService.list(new QueryWrapper<AsnDetail>().eq("bill_no", billNo.trim()));
        if (ObjectUtil.isNotEmpty(asnMaster)) {
            if (asnMaster.getAsnType().equals(AsnManageConstant.ASN_CLOSE)) {
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "任务单已关闭");
            }
            List<AsnDetail> newAsnDetail = asnDetails.stream().filter(item -> item.getAcceptQuantity() < item.getExpectQuantity()).collect(Collectors.toList());
            asnMaster.setAsnDetails(newAsnDetail);
        }
        if (ObjectUtil.isEmpty(asnMaster)) {
            Map<String, Object> map = new HashMap<>();
            map.put("billNo", billNo);
            asnMaster = asnMasterService.erpByBillNo(map);

        }
        return ResultGenerator.genSuccessResult(asnMaster);
    }


    @ApiOperation(value = "归档ASN信息 传billNo", notes = "归档ASN信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/file")
    public Result file(@RequestBody List<AsnMaster> asnMasters, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        for (AsnMaster asnMaster : asnMasters) {
            Map<String,Object> cbMap = new HashMap();
            cbMap.put("billTypeId", asnMaster.getBillType());
            cbMap.put("billId", asnMaster.getBeforeNum());
            CompletableFuture.runAsync(() -> {
                pushErpService.CheckBill(cbMap);
            });
        }
//        for (int i = 0; i < fileData.getBillNos().size(); i++) {
//            String billNo = fileData.getBillNos().get(i);
//            asnMasterService.createFile(billNo, currentUser);
//        }

        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "ASN单据导入", notes = "ASN单据导入")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @Transactional
    @PostMapping("/importAsnBills")
    public Result importAsnBills(AsnImport excel, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER);
        }

        jxl.Workbook billWorkbook = null;


        String msg = "Excel 内容有问题，无法导入！";

        try {
            billWorkbook = jxl.Workbook.getWorkbook(excel.getModel().getInputStream());
            jxl.Sheet billSheet = billWorkbook.getSheet(0);

            int rows = billSheet.getRows();

            AsnMaster asnMaster = new AsnMaster();

            String tableName = "so_master";
            //TODO:主键如何处理
//            Integer nextId = validatorService.getNextId(tableName);
//            asnMaster.setId(nextId);
            asnMasterService.save(asnMaster);
            String billNo = "ASN" + "-" + asnMaster.getId();


            String wareName = ExcelUtils.getCellString(billSheet, 0, 2).trim();
            Integer wareId = null;
            WareInfo wareInfo = wareInfoService.getOneByField("ware_name", wareName);
            if (wareInfo != null) {
                wareId = wareInfo.getWareId();

            } else {
                msg = "仓库名称错误！" + wareName;
                throw new Exception();
            }

            String organizationName = ExcelUtils.getCellString(billSheet, 1, 2).trim();
            Integer organizationId = null;
            Organization organization = organizationService.findBy("organization_name", organizationName);
            if (organization != null) {
                organizationId = organization.getOrganizationId();

            } else {
                msg = "货主名称错误！" + organizationName;
                throw new Exception();
            }
            String supplierName = ExcelUtils.getCellString(billSheet, 2, 2).trim();
            Integer supplierId = null;
            SupplierManage supplierManage = supplierManageService.findBy("supplier_name", supplierName);
            if (supplierManage != null) {
                supplierId = supplierManage.getSupplierId();

            } else {
                msg = "供应商名称错误！" + supplierName;
                throw new Exception();
            }

            String platformCode = ExcelUtils.getCellString(billSheet, 3, 2).trim();
            String carrierName = ExcelUtils.getCellString(billSheet, 3, 2).trim();
            String carrierCode = null;
            Carrier carrier = carrierService.findBy("carrier_name", carrierName);
            if (carrier != null) {
                carrierCode = carrier.getCarrierCode();

            } else {
                msg = "承运方名称错误！" + organizationName;
                throw new Exception();
            }

            String loadingPlace = ExcelUtils.getCellString(billSheet, 4, 2).trim();
            String deliveryPlace = ExcelUtils.getCellString(billSheet, 4, 2).trim();
            String trafficDescribe = ExcelUtils.getCellString(billSheet, 4, 2).trim();
            String asnUdfHs1 = ExcelUtils.getCellString(billSheet, 4, 2).trim();
            String asnUdfHs2 = ExcelUtils.getCellString(billSheet, 4, 2).trim();
            String asnUdfHs3 = ExcelUtils.getCellString(billSheet, 4, 2).trim();
            String expectTime = ExcelUtils.getCellString(billSheet, 4, 2).trim();

            String createUserName = ExcelUtils.getCellString(billSheet, 3, 2).trim();
            Integer userId = null;
            QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
            wrapper.eq("createUserName", createUserName);
            UserInfo userInfo = userInfoService.getOne(wrapper);
            if (userInfo != null) {
                userId = userInfo.getUserId();
            } else {
                msg = "承运方名称错误！" + organizationName;
                throw new Exception();
            }

            String memo = ExcelUtils.getCellString(billSheet, 9, 2);
            asnMaster.setWareId(wareId);
            asnMaster.setWareName(wareName);
            asnMaster.setOrganizationId(organizationId);
            asnMaster.setOrganizationName(organizationName);
            asnMaster.setSupplierId(supplierId);
            asnMaster.setSupplierName(supplierName);
            asnMaster.setPlatformCode(platformCode);
            asnMaster.setCarrierCode(carrierCode);
            asnMaster.setLoadingPlace(loadingPlace);
            asnMaster.setDeliveryPlace(deliveryPlace);
            asnMaster.setTrafficDescribe(trafficDescribe);
            asnMaster.setAsnUdfHs1(asnUdfHs1);
            asnMaster.setAsnUdfHs2(asnUdfHs2);
            asnMaster.setAsnUdfHs3(asnUdfHs3);
            asnMaster.setState(0);
            asnMaster.setCreateUserId(userId);
            asnMaster.setCreateUserName(createUserName);
            asnMaster.setOrderNo(1);
            asnMaster.setExpectTime(expectTime);
            asnMaster.setBillSource(4); //导入
            asnMaster.setMemo(memo);

            Integer state = caseMasterService.createCase(billNo, 2, currentUser.getUserId(), wareId, organizationId);

            asnMaster.setState(state);


            asnMasterService.updateById(asnMaster);


            Integer rowCount = 0;
            for (int i = 6; i < rows; i++) {
                String content = ExcelUtils.getCellString(billSheet, 1, i);
                if (content == null || "".equals(content)) {
                    break;
                }
                rowCount++;
            }

            for (int i = 6; i < rowCount + 6; i++) {
                String itemName = ExcelUtils.getCellString(billSheet, 0, i).trim();
                if (itemName == null) {
                    msg = "缺少物料名称！" + itemName;
                    throw new Exception();
                }

                String packDescribe = ExcelUtils.getCellString(billSheet, 1, i);
                if (packDescribe == null) {
                    msg = "缺少单位！" + packDescribe;
                    throw new Exception();
                }

                Double expectQuantity = ExcelUtils.getCellDouble(billSheet, 2, i);
                if (expectQuantity == null) {
                    msg = "缺少预期到货数量！" + expectQuantity;
                    throw new Exception();
                }

                String memo1 = ExcelUtils.getCellString(billSheet, 3, i);
                String asnUdfDs1 = ExcelUtils.getCellString(billSheet, 4, i);
                String asnUdfDs2 = ExcelUtils.getCellString(billSheet, 5, i);
                String asnUdfDs3 = ExcelUtils.getCellString(billSheet, 6, i);
                ItemInfo itemInfo = itemInfoService.findBy("item_name", itemName);
                PackDetail packDetail = packDetailService.findBy("pack_describe", packDescribe);

                AsnDetail asnDetail = new AsnDetail();

                asnDetail.setBillNo(billNo);
                asnDetail.setDetailNo(billNo + "-" + (i - 6 + 1));
                asnDetail.setItemCode(itemInfo.getItemCode());
                asnDetail.setItemName(itemName);
                asnDetail.setPackDetailId(packDetail.getPackDetailId());
                asnDetail.setPackDescribe(packDescribe);
                asnDetail.setExpectQuantity(expectQuantity);
                asnDetail.setMemo(memo1);
                asnDetail.setAsnUdfDs1(asnUdfDs1);
                asnDetail.setAsnUdfDs2(asnUdfDs2);
                asnDetail.setAsnUdfDs3(asnUdfDs3);

                asnDetailService.save(asnDetail);

            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(CommonCode.WRONG_EXCEL_CONTENT, msg);

        } finally {
            billWorkbook.close();
        }

        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/list2")
    public Result list2(AsnMasterCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<AsnMasterDto> list = asnMasterService.findList2(criteria);
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "新增先发配件入库信息", notes = "新增先发配件入库信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/insert2")
    public Result add2(@RequestBody AsnData asnData, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        asnMasterService.createAsnMaster2(asnData, currentUser);
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("savePurchaseOrder")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    public Result savePurchaseOrder(String date) {
        Map<String, Object> map = new HashMap<>();
        map.put("currentPage", 1);
        map.put("pageSize", 10000);
        asnMasterService.savePurchaseOrder(map);
        return ResultGenerator.genSuccessResult();
    }



    @GetMapping("allotPrint/{billNo}")
    public Result allotPrint(@PathVariable String billNo,@ApiIgnore @User CurrentUser currentUser) {

        return ResultGenerator.genSuccessResult(asnMasterService.allotPrint(billNo,currentUser));
    }



    /**
     * 产品入库--上架
     */
    @ApiOperation(value = "WMS产品入库(数据回传ERP)", notes = "WMS产品入库(数据回传ERP)")
    @GetMapping("/toPutaway")
    public Result toPutaway(AsnMasterCriteria criteria, @ApiIgnore @User CurrentUser currentUser) {
        // 获取选中的入库任务
        // 解析前台
        List<Integer> idList = new ArrayList<>();
        String ids = criteria.getIds();
        if (ids != null && !ids.equals("")) {
            // 按照逗号分隔成多个任务单号
            String[] list = ids.split(",");
            for (String id : list) {
                idList.add(Integer.parseInt(id));
            }
        }
        List<AsnMaster> asnMasters = asnMasterService.listByIds(idList);
        // 每一条明细对应一个库存事务
        for (AsnMaster asnMaster : asnMasters) {
            asnMasterService.accomplish(asnMaster, criteria.getCellCode(), currentUser);
//            acceptRecordService.createByAsnDetail(asnMaster, criteria.getCellCode(), currentUser);
            // 修改入库任务状态
            asnMaster.setAsnState(3);
            asnMasterService.updateById(asnMaster);
        }

        // 回传erp
        for(AsnMaster asnMaster:asnMasters){
            acceptRecordService.toERP(criteria.getCellCode(),asnMaster);
        }
        return ResultGenerator.genSuccessResult();
    }


//    @PostMapping("inputAsn")
//    @Transactional
//    public Result inputAsn(MultipartFile file) {
//
//        List<InputAsnMaster> inventoryList = null;
//        try {
//            inventoryList = Excel.readExcelFile(file.getInputStream(), InputAsnMaster.class, file.getOriginalFilename());
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        List<AsnMaster> asnMasterList = new ArrayList<>();
//        Map<String, InputAsnMaster> convertMap = convertMap(inventoryList, InputAsnMaster::getBillNo);
//        convertMap.forEach((key,inputAsnMaster)->{
//            if (ObjectUtil.isEmpty(inputAsnMaster.getBillNo())) {
//                return;
//            }
//            AsnMaster asnMaster = new AsnMaster();
//            asnMaster.setBillNo(inputAsnMaster.getBillNo());
//            asnMaster.setSupplierId(inputAsnMaster.getSupplierId());
//            asnMaster.setSupplierName(inputAsnMaster.getSupplierName());
//            asnMaster.setBillType(702);
//            asnMaster.setAsnType("外购入库".equals(inputAsnMaster.getAsnTypeName()) ? 1 : 5);
//            asnMaster.setWareId(285);
//            asnMaster.setWareName("如高高压");
//            asnMaster.setOrganizationId(-1);
//            asnMaster.setOrganizationCode("SYS_MINE");
//            asnMaster.setOrganizationName("只有");
//            asnMaster.setNotQc(1);
//            asnMasterList.add(asnMaster);
//        });
//
//
//        List<AsnDetail> asnDetails = new ArrayList<>();
//            Integer i = 1;
//            for (InputAsnMaster inputAsnMaster : inventoryList) {
//                if (ObjectUtil.isEmpty(inputAsnMaster.getBillNo())) {
//                    continue;
//                }
//                AsnDetail asnDetail = new AsnDetail();
//                asnDetail.setBillNo(inputAsnMaster.getBillNo());//ASN单号
//                asnDetail.setPackDetailId(33469);//基本单位ID
//                asnDetail.setPackDescribe("件");//单位
//                asnDetail.setItemCode(inputAsnMaster.getItemCode());//物料编码
//                asnDetail.setItemName(inputAsnMaster.getItemName());//物料名称
//                asnDetail.setSourceId(inputAsnMaster.getSourceId());
//                asnDetail.setUda1(inputAsnMaster.getModel());//规格型号
//                asnDetail.setDetailNo(inputAsnMaster.getBillNo() + "-" + i);
//                asnDetail.setStockId(inputAsnMaster.getStockId());  //仓库id
//                asnDetail.setStockName(inputAsnMaster.getStockName()); //仓库名称
//                System.out.println(i);
//                asnDetail.setExpectQuantity(inputAsnMaster.getQcNum() - inputAsnMaster.getInputNum());//待检数量,为全部数量
//                asnDetail.setRowIndex(inputAsnMaster.getRowIndex());//行号
//                asnDetail.setVersion(inputAsnMaster.getVersion()); //执行版本
//                asnDetail.setLatestVersion(inputAsnMaster.getLatestVersion()); //现行版本
//                asnDetails.add(asnDetail);
//                i++;
//            }
//
//            asnMasterService.saveBatch(asnMasterList);
//            asnDetailService.saveBatch(asnDetails);
////        throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "验收货位无效！");
//        return null;
////        return null;
//    }

    @Autowired
    private PushErpService pushErpService;

    @GetMapping("/erpAudit/{id}")
    public void erpAudit(@PathVariable Integer id) {
        AsnMaster asnMaster = asnMasterService.getById(id);
        Map<String,Object> cbMap = new HashMap();
        cbMap.put("billTypeId", asnMaster.getBillType());
        cbMap.put("billId", asnMaster.getBeforeNum());
        pushErpService.CheckBill(cbMap);
        List<AsnDetail> asnDetails = asnMaster.getAsnDetails();
        asnMasterService.saveOrUpdate(asnMaster);
        asnDetailService.saveOrUpdateBatch(asnDetails);
    }

    @Autowired
    private CellInfoService cellInfoService;
   @GetMapping("findCategoryId")
    public Result findCategoryId(String billNo,String cellCode) {
        AsnMaster asnMaster = asnMasterService.getOne(new QueryWrapper<AsnMaster>().eq("bill_no", billNo).last("limit 1"));
       AreaInfo areaByCell = cellInfoService.findAreaByCell(cellCode);
       List<String> categoryIds = new ArrayList<>();
       categoryIds.add("559967");
       Integer categoryId = Optional.ofNullable(asnMaster.getCategoryId()).orElse(null);
       Integer waveType = Optional.ofNullable(areaByCell).map(item -> item.getWaveType()).orElse(0);
     return ResultGenerator.genSuccessResult(!categoryIds.contains(Convert.toStr(categoryId)) && Convert.toStr(waveType).equals("1"));

    }

}
